#include "Entity.h"
#include "Engine/Engine.h"
#include "Item/ItemFactory.h"
#include "World Module.h"

#define d_engine		Engine::Ins() 
#define d_factory		Factory::get() 
#define d_ScreenAngle	(float)(Engine::Ins()->game.getAngleToScreen())
#define d_PlayerAngle	(float)(Engine::Ins()->game.getAngleBetweenPoints


//=====CONSTRUCTORS/DECONTSRUCTORS
Entity::Entity()
	: BaseObject(0, 0, -1), bGravity(true), bDummy(false), uniqueID(-1)
{
	timer.init(20);
	lastXDir = DIR_RIGHT;
	playerIndex = -1;		// used for multiplayer only ~ added by Michael A.
	entityType	= -1;
	score		= 0;
	objectType	= TYPE_ENTITY_PIECE;
	alive = true;
	sprintAcceleration	= 0;
	sprintMaxSpeed		= 0;
	PierceThreshold, resistPierce, currentPierce = 0;
	ImpactThreshold, resistImpact, currentImpact = 0;
	EnergyThreshold, resistEnergy, currentEnergy = 0;
	oneTenthSecond.init(100);
	oneSecondTimer.init(1000);
	twoSecondTimer.init(2000);
	humanReactionTimer.init(500);
	attackTimer.init(0);

	Mania		= 0;
	Aggression	= 20;
	Discipline	= 0;
	agroSphere, flockRange, wanderRange = 0;

	Meta		= 0.0f;
	myJumpState	= stateJumpFall;
	for(int i = 0; i < WAV_MAXSOUNDS; i++)	activeSounds[i] = false;
	for(int i = 0; i < MaxEquipables; i++)	wornEquipment[i] = NULL;
	for(int i = 0; i < ACT_MAX; i++)		CurrentActivity[i] = NULL;
	for(int i = 0; i < ANI_MAX; i++){
		currentFrames[i] = 0;
		activeAnimations[i] = false;
	}
}
Entity::~Entity()
{
	for(int  i = 0; i < e_TotalBPs; i++)
	{
		delete BodyParts[i];
	}
	Inventory.clear();
}
//End of (DE)Constructors


////////////////////////////
//~~~~~Private Initializers(Loading, Saving, Destroying)
////////////////////////////
void Entity::destroyCharacter()
{
	for(int  i = 0; i < e_TotalBPs; i++)
	{
		Engine::Ins()->dlHandler.RemoveObjectByRef(DRAW_ENTITIES, BodyParts[i]);
		SkinAssets[i] = BodyParts[i]->assetIndex;
	}
	Engine::Ins()->dlHandler.RemoveObjectByRef(DRAW_ENTITIES, this);

	// TODO: Manage all memory properly
}
void Entity::loadCharacter(char* s_Charactersheet, int ent_type)
{
	m_v3Pos.z = 2.0f;
	ms_Charactersheet = s_Charactersheet;
	entityType = ent_type;

	if(entityType == P_TYPE_ENEMY)
		playerIndex = -2;
	Stats.LoadStats(s_Charactersheet, Race);

	//~~~~~~Time for ze calculating of Entity Attributes!
	Stats.CalcSpeedAttributes(sprintAcceleration, sprintMaxSpeed);
	Stats.CalcNaturalResistances(resistPierce, resistImpact, resistEnergy);
	Stats.CalcThresholds(PierceThreshold, ImpactThreshold, EnergyThreshold);
	Stats.CalcAttSpeed(attackSpeed, STAT_WEAPONRY);
	attackTimer.init(attackSpeed);
	//~~~~~~Everysching is Calculcated

	//Create the limbs of this entity
	Engine::Ins()->dlHandler.AddObject(this, DRAW_ENTITIES);

	CreateLimbs(ent_type);

	this->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x", "Resources/Sprites/Entity/Blank.png", NULL, NULL, ASSET_WORLD);
}
void Entity::saveCharacter(char* s_Charactersheet)
{
	Stats.SaveStats(Stats, s_Charactersheet, Race);
}
void Entity::CreateLimbs(int ent_type)
{
	for(int i = 0; i < e_TotalBPs; ++i)
	{
		BodyParts[i] = new BaseObject;
		BodyParts[i]->objectType = TYPE_ENTITY_PIECE;
	}
	for(int  i = 0; i < e_TotalBPs; i++)
	{
		BodyParts[i]->SetPos(m_v3Pos);
		Placements[i].setXY((short)m_v3Pos.x, (short)m_v3Pos.y);
	}

	Placements[e_Head].X		= -0.5f;	Placements[e_Head].Y = -5;			Placements[e_Head].Z = 0;
	Placements[e_UpperArm].X	= 0;		Placements[e_UpperArm].Y = 0;		Placements[e_UpperArmleft] = Placements[e_UpperArm];
	Placements[e_LowerArm].X	= 0;		Placements[e_LowerArm].Y = 4; 		Placements[e_LowerArmleft] = Placements[e_LowerArm]; Placements[e_LowerArm].Z = 2;
	Placements[e_Torso].X		= 0;		Placements[e_Torso].Y = 0;
	Placements[e_Thighs].X		= 0;		Placements[e_Thighs].Y = 6;			Placements[e_Thighsleft] = Placements[e_Thighs];	Placements[e_Thighsleft].Z = 1;
	Placements[e_Legs].X		= 0;		Placements[e_Legs].Y = 10;			Placements[e_Legsleft] = Placements[e_Legs];	Placements[e_Legsleft].Z = 1;

	for(int  i = 0; i < e_TotalBPs; i++)
	{
		float x, y, z = 0; 
		Rotations[i].X = 0; Rotations[i].Y = 0; Rotations[i].Z = 0;
		x = BodyParts[i]->getPos().x - Placements[i].X;
		y = BodyParts[i]->getPos().y - Placements[i].Y;
		z = BodyParts[i]->getPos().z - Placements[i].Z;
		BodyParts[i]->SetPos(x, y, z);
		BodyParts[i]->setScale(Vector3D(0.5f, 0.5f, 0.0f));
	}
	DetermineRace();

	for(int  i = 0; i < e_TotalBPs; i++)
	{
		Engine::Ins()->dlHandler.AddObject(BodyParts[i], DRAW_ENTITIES);
		SkinAssets[i] = BodyParts[i]->assetIndex;
	}
}
void Entity::DetermineRace()
{
	if(Race == 1) //If it's a human
	{
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Human/Head.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Torso]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/torso.x"					, "Resources/Sprites/Entity/Human/Body.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArm]->assetIndex= Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Human/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/Human/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArm]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Human/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/Human/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Human/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Human/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Human/Foot.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Human/Foot.png", NULL, NULL, ASSET_WORLD);

		wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::bowieKnife);
		wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
		Engine::Ins()->dlHandler.AddObject(wornEquipment[Weaponry], DRAW_ENTITIES);


		if(GUI_Handler::get().needsToRefreshInventory())
		{
			GUI.get().setInventory(Inventory);
			GUI.get().setEquipment((Item_Base**)(wornEquipment),MaxEquipables);
		}
	}
	if(Race == 2) //If it's a zambie!
	{
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Zombie/Head.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Torso]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/torso.x"					, "Resources/Sprites/Entity/Zombie/Body.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArm]->assetIndex= Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Zombie/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/Zombie/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArm]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Zombie/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/Zombie/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Zombie/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Zombie/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/Zombie/Foot.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/Zombie/Foot.png", NULL, NULL, ASSET_WORLD);

		wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::bowieKnife);
		wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
		Engine::Ins()->dlHandler.AddObject(wornEquipment[Weaponry], DRAW_ENTITIES);
	}

	if(Race == 3) //If it's a CQCDrone!
	{
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/CQCDrone/Head.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Torso]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/torso.x"					, "Resources/Sprites/Entity/CQCDrone/Body.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArm]->assetIndex= Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/CQCDrone/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/CQCDrone/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArm]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/CQCDrone/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/CQCDrone/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/CQCDrone/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/CQCDrone/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/CQCDrone/Foot.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/CQCDrone/Foot.png", NULL, NULL, ASSET_WORLD);

		int type = (rand() % 2);
		type == 0 ? wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::bowieKnife) : wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::energyMace);
		wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
		Engine::Ins()->dlHandler.AddObject(wornEquipment[Weaponry], DRAW_ENTITIES);
	}
	if(Race == 4) //If it's a Ranged!
	{
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/RangedDrone/Head.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Torso]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/torso.x"					, "Resources/Sprites/Entity/RangedDrone/Body.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArm]->assetIndex= Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/RangedDrone/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_UpperArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/RangedDrone/Arm.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArm]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/RangedDrone/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_LowerArmleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/RangedDrone/Hand.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/RangedDrone/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Thighsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"	, "Resources/Sprites/Entity/RangedDrone/Thigh.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legs]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"			, "Resources/Sprites/Entity/RangedDrone/Foot.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Legsleft]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x"		, "Resources/Sprites/Entity/RangedDrone/Foot.png", NULL, NULL, ASSET_WORLD);

		int type = (rand() % 2);
		type == 0 ? wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::handGun) : wornEquipment[Weaponry] = Factory::get().makeEquippable(Factory::ehandGun);
		wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
		Engine::Ins()->dlHandler.AddObject(wornEquipment[Weaponry], DRAW_ENTITIES);
	}
}


////////////////////////
//====Private Mutators(Momentum and Flipping)
////////////////////////
void Entity::CalcMomentum()
{
	FinalMomentum = Momentums[MOM_INPUT];

	m_v3Pos.x += FinalMomentum.x;
	m_v3Pos.y += FinalMomentum.y;

	if(FinalMomentum.y < 0)
		myJumpState = stateJumpFall;

	if(FinalMomentum.x < 0)	{lastXDir = DIR_LEFT;	Flip(DIR_LEFT);}
	if(FinalMomentum.x > 0)	{lastXDir = DIR_RIGHT;	Flip(DIR_RIGHT);}
}
void Entity::Flip(int lastXDir)
{
	if(lastXDir == DIR_LEFT)
	{
		Placements[e_Head].X = 0.5f;
		for(int  i = 0; i < e_TotalBPs; i++)
			Rotations[i].X = D3DXToRadian(180);
	}
	if(lastXDir == DIR_RIGHT)
	{
		Placements[e_Head].X = -0.5f;
		for(int  i = 0; i < e_TotalBPs; i++)
			Rotations[i].X = 0;
	}
}


////////////////////////
//=====Private Updates(Items, Effects, Stats, Limbs)
////////////////////////
void Entity::UpdateWornItems()
{
	if(wornEquipment[Weaponry] != NULL){
		Vector3D itemPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, (float)(BodyParts[e_LowerArm]->getPos().z - 1));
		Vector3D itemRot(BodyParts[e_LowerArm]->getRotation());
		//itemPos.y -= 1;
		if(lastXDir == DIR_RIGHT)
			itemPos.x += 2;
		else
			itemPos.x -= 2;
		wornEquipment[Weaponry]->SetPos(itemPos);
		wornEquipment[Weaponry]->setRotation(itemRot.x, itemRot.y, itemRot.z +  D3DXToRadian(-75));
	}
}
void Entity::UpdateEffects()
{
	int currStattoAffect;
	int currAmount;
	int positionofStat = -1;
	for(int x = 0; x < EffectList.size(); ++x)
	{
		if(EffectList[x].isOverTime)
		{
			for(int y = 0; y < EffectList[x].curElements; ++y)
			{
				currStattoAffect	= EffectList[x].buffList[y].statToAffect;
				currAmount			= EffectList[x].buffList[y].amount;
				switch(currStattoAffect)
				{
				case MSTAT_CURRPIERCE:
					if((currentPierce + currAmount) <= 0)
					{
						currentPierce = 0;
						break;
					}
					if((currentPierce + currAmount) >= PierceThreshold)
					{
						currentPierce = PierceThreshold;
						break;
					}
					currentPierce += currAmount;
					break;
				case MSTAT_CURRIMPACT:
					if((currentImpact + currAmount) <= 0)
					{
						currentImpact = 0;
						break;
					}
					if((currentImpact + currAmount) >= ImpactThreshold)
					{
						currentImpact = ImpactThreshold;
						break;
					}
					currentImpact += currAmount;
					break;
				case MSTAT_CURRENERGY:
					if((currentEnergy + currAmount) <= 0)
					{
						currentEnergy = 0;
						break;
					}
					if((currentEnergy + currAmount) >= EnergyThreshold)
					{
						currentEnergy = EnergyThreshold;
						break;
					}
					currentEnergy += currAmount;
					break;
				case MSTAT_CURRMANIA:
					break;
				case MSTAT_CURRDISCIPLINE:
					break;
				case MSTAT_CURRAGRESSION:
					break;
				case MSTAT_META:
					break;
				}
			}			
		}
		EffectList[x].duration--;
	}
	for(int x = 0; x < EffectList.size(); ++x)
	{
		if(EffectList[x].duration <= 0)
		{
			if(!EffectList[x].isOverTime)
				for(int i = 0; i < EffectList[x].curElements; i++)
					Stats.Stats[EffectList[x].buffList[i].statToAffect] -= EffectList[x].buffList[i].amount;
			EffectList.remove(x);
		}
	}
};
void Entity::UpdateStatistics()
{
	Stats.CalcSpeedAttributes(sprintAcceleration, sprintMaxSpeed);
	Stats.CalcNaturalResistances(resistPierce, resistImpact, resistEnergy);
	if(wornEquipment[Helmet] != NULL) wornEquipment[Helmet]->addPIE(resistPierce,resistImpact,resistEnergy);
	if(wornEquipment[Cuirass] != NULL) wornEquipment[Cuirass]->addPIE(resistPierce,resistImpact,resistEnergy);
	if(wornEquipment[Gauntlets] != NULL) wornEquipment[Gauntlets]->addPIE(resistPierce,resistImpact,resistEnergy);
	if(wornEquipment[Boots] != NULL) wornEquipment[Boots]->addPIE(resistPierce,resistImpact,resistEnergy);
	Stats.CalcThresholds(PierceThreshold, ImpactThreshold, EnergyThreshold);

	short skilltouse;
	wornEquipment[Weaponry] != NULL ? skilltouse = wornEquipment[Weaponry]->skillAlignment : skilltouse = STAT_WEAPONRY;
	short prevAttackspeed = attackSpeed;
	Stats.CalcAttSpeed(attackSpeed, skilltouse);
	if(attackSpeed != prevAttackspeed)
		attackTimer.init(attackSpeed);

	//short 
	if(Meta + Stats.Stats[STAT_MTP] > Stats.CalcMaxMeta())
		Meta = Stats.CalcMaxMeta();
	else 
		Meta += (Stats.CalcMetaRegen());
}
void Entity::UpdateLimbs()
{
	for(int  i = 0; i < e_TotalBPs; i++)
	{
		float x, y, z = 0;
		BodyParts[i]->SetPos(m_v3Pos);
		x = BodyParts[i]->getPos().x - Placements[i].X;
		y = BodyParts[i]->getPos().y - Placements[i].Y;
		z = BodyParts[i]->getPos().z - Placements[i].Z;
		BodyParts[i]->SetPos(x, y, z);
		BodyParts[i]->setRotation(Rotations[i].X, Rotations[i].Y, Rotations[i].Z);
	}
}


////////////////////////
//======Primary Update
////////////////////////
bool Entity::UpdateEntity(Vector<Entity*> * EntityList)
{
	if(alive == true) //Added to test when death occurs
	{
		HandleMovement();
		HandleActions();
	}
	//=====Entity throttle, Stop them from going over their max
	if(fabs(Momentums[0].x) >= sprintMaxSpeed)
	{
		if (myJumpState == stateNeutral)
			activeAnimations[ANI_RUN] = true;
		if(Momentums[0].x > 0)	Momentums[0].x = (float)sprintMaxSpeed;
		else					Momentums[0].x = (float)sprintMaxSpeed * -1.0f;
	}

	//=====Jumping
	if(myJumpState  != stateNeutral)
	{
		bGravity = true;
		Momentums[0].y += Gravity;
	}
	else
		bGravity = false;

	//=====Move and Align
	CalcMomentum();
	UpdateLimbs();
	UpdateWornItems();

	if(oneTenthSecond.update())		UpdateStatistics();
	if(oneSecondTimer.update())		UpdateEffects();

	if(entityType == P_TYPE_PLAYER)
	{
		//Yup, could be cleaner, but we've got deadlines and this isn't that bad when you factor that in.
		//Mmm, taste that featurecreep
		GUI.get().setPIE(Vector3D(
			float(currentPierce*100/PierceThreshold),
			float(currentImpact*100/ImpactThreshold),
			float(currentEnergy*100/EnergyThreshold)));
		GUI.get().setMaxHealth(Vector3D(PierceThreshold,ImpactThreshold,EnergyThreshold));
		GUI.get().setDamage(Vector3D(currentPierce,currentImpact,currentEnergy));
		GUI.get().setDefenses(Vector3D(resistPierce,resistImpact,resistEnergy));
		GUI.get().setMeta(Meta*100/(float)Stats.CalcMaxMeta());

	}
	else if(entityType == P_TYPE_ENEMY)
	{
		NPC_HandleAI(EntityList);		
	}
	return true;
}


////////////////////////
//====Actions(ActionLists)
////////////////////////
void Entity::HandleMovement()
{
	int Inputready;
	int TotalMessages;
	if(MovementQueue.size())
		TotalMessages = MovementQueue.size();
	else
		return;
	for (int i = 0; i < TotalMessages; ++i)
	{
		if(MovementQueue.size() != 0)	Inputready = MovementQueue[0];
		else							Inputready = NONE;

		switch(Inputready)
		{
		case NONE:
			if(fabs(Momentums[0].x) >= 1)		Momentums[0].x /= (float)sprintAcceleration;
			if(fabs(Momentums[0].x) < 1)		Momentums[0].x = 0;
			break;
		case LEFT:	
			if(!CollidedDirections[DIR_LEFT])
			{
				lastXDir = DIR_LEFT;
				Momentums[0].x -= (float)sprintAcceleration;
			}

			break;
		case RIGHT:	
			if(!CollidedDirections[DIR_RIGHT])
			{
				lastXDir = DIR_RIGHT;
				Momentums[0].x += (float)sprintAcceleration;	
			}
			break;
		case UP:	
			if(myJumpState	== stateNeutral) 
			{
				activeAnimations[ANI_JUMP] = true;
				Momentums[0].y	= Stats.calcJumpImpulse();
				myJumpState		= stateJumpRise;
			}
			break;
		}
		MovementQueue.remove(0);
	}
}
void Entity::HandleActions()
{
	int Inputready;
	int TotalMessages = ActivityQueue.size();
	for (int i = 0; i < TotalMessages; ++i)
	{
		if(ActivityQueue.size() != 0)	Inputready = ActivityQueue[0];
		else							Inputready = NONE;
		switch(Inputready)
		{
			//--------------------GUI/ATTACKING---------------//
		case NONE:														break;
		case CHARGE:		chargeSpell();								break;
		case CREATESPELL:	createSpell();								break;
		case CAST:			castSpell();								break;
		case SWING:			SwingWeapons();								break;
		case INVCHECK:		GUI_Handler::get().setInventory(Inventory);	break;
		case CRAFTCHECK:	GUI_Handler::get().setCrafTable(Inventory);	break;
		case SAVE:			saveCharacter(ms_Charactersheet);			break;
		}
		ActivityQueue.remove(0);
	}
}
void Entity::WipeActionList()
{
	for(int i = 0; i < 6; i++)
		CurrentActivity[i] = NULL;
}
Item_Projectile* Entity::GetCurrentAction(int p_index)
{return CurrentActivity[p_index];}


////////////////////////
//=====ProjectileCasting (Swinging, Casting)
////////////////////////
void Entity::createSpell()
{
	if(Meta > 10)
	{
		float Angle = 0;
		if(entityType == P_TYPE_PLAYER)
			Angle = d_ScreenAngle;
		if(entityType == P_TYPE_ENEMY)
			Angle = d_PlayerAngle(m_v3Pos, AI_TargetPos));

		CurrentActivity[ACT_MAGIC] = 
			d_factory.buildProjectile(m_v3Pos,
			Angle,12,true, false, 
			200, entityType, Vector3D(0,0,30),
			d_factory.fireBall);
		CurrentActivity[ACT_MAGIC]->collideEffect =  Item_Projectile::SPELL_FIREBALL;
		Engine::Ins()->dlHandler.AddObject(CurrentActivity[ACT_MAGIC], DRAW_ENTITIES);
		Meta -= 10;
	}
}
void Entity::castSpell()
{
	if(CurrentActivity[ACT_MAGIC] != NULL)
	{
		activeSounds[WAV_FIREBALL] = true;
		CurrentActivity[ACT_MAGIC]->movementOn = true;
		Engine::Ins()->game.m_network.MakeServerRequest(NETWORK_SEND_PROJECTILE, CurrentActivity[ACT_MAGIC], 0);
		CurrentActivity[ACT_MAGIC] = NULL;
	}
};
void Entity::chargeSpell()
{
	if(CurrentActivity[ACT_MAGIC] != NULL)
	{
		//If a spell is currently being held, then have it follow the player and grow in size
		CurrentActivity[ACT_MAGIC]->SetPos(Vector3D((int)m_v3Pos.x, (int)m_v3Pos.y, (int)m_v3Pos.z));
		//CurrentActivity[ACT_MAGIC]->setScale(Vector3D(CurrentActivity[6]->getScale().x + 0.1f, CurrentActivity[6]->getScale().y + 0.1f, CurrentActivity[6]->getScale().z));
	}
	else
	{

	}
}
void Entity::SwingWeapons()
{
	float Angle = 0;
	if(wornEquipment[Weaponry] != 0 && attackTimer.update())
	{
		activeAnimations[ANI_SWING] = true;

		if(wornEquipment[Weaponry]->getRange() >= 20)
		{
			activeSounds[WAV_GUNSHOT] = true;
		}
		else
			activeSounds[WAV_SWOOSH] = true;


		if(entityType == P_TYPE_PLAYER)
			Angle = d_ScreenAngle;
		if(entityType == P_TYPE_ENEMY)
			Angle = d_PlayerAngle(m_v3Pos, AI_TargetPos));

		Vector3D temp = BodyParts[e_Torso]->getPos();
		d_factory.makeCollider(
			Vector3D(temp.x,temp.y + 3,temp.z),
			Angle,10, false, true,
			wornEquipment[Weaponry]->getRange()+2,			//How far before it deletes itself
			entityType,
			wornEquipment[Weaponry]->getPIE()		//Pierce - Impact - Energy
			,(wornEquipment[Weaponry]->m_placeBlock?Item_Projectile::SPELL_PLACEBLOCK:Item_Projectile::SPELL_WEAPONRY),
			wornEquipment[Weaponry]->itemName);	
	}
}
bool Entity::projectileHasHit(Item_Projectile* item,int Tex, Vector2D iconAsset, char* Name)
{
	bool retValue = true;


	switch(item->collideEffect)
	{
	case Item_Projectile::SPELL_FIREBALL:
	case Item_Projectile::SPELL_WEAPONRY:
		{
			//Brandon York
			if(Name == "Trophy") 
			{
				PC_handleScore(10);
				Engine::Ins()->game.ReloadState();
			}
			else 
			{
				if(Engine::Ins()->game.autoLootWorldBlocks)
				{
				Item_Equippable* matToEquip = new Item_Equippable;
				matToEquip->_itemInit(ITEM_EQUIPPABLE,45,0,Name);
				matToEquip->_equipInit(WEAP,0,0,0,100);
				matToEquip->setScale(0.45f,0.45f,0.45f);
				matToEquip->assetIndex	 = Vector2D(ASSET_WORLD,Tex);
				matToEquip->iconAsset	 = iconAsset;
				matToEquip->m_placeBlock = true;
				retValue = AddItemtoInv(matToEquip);
				if(!retValue)
					activeSounds[WAV_ERROR] = true;
				}
			}
			break;
		}
	case Item_Projectile::SPELL_MULTIPLAYER_DUD:
		item->movementOn = false;
		retValue = false;
		break;
	}

	return retValue;
}


////////////////////////
//====Inventory Mutators
////////////////////////
bool Entity::AddItemtoInv(Item_Base* p_Basey)
{
	if(Inventory.size() < 84)
	{
		GUI.get().setMessage(p_Basey->itemName," added",GUI_Handler::NOTIFICATION);
		Inventory.push(p_Basey);
		return true;
	}
	GUI.get().setMessage("Inventory Full!",GUI_Handler::NOTIFICATION);
	return false;
}
bool Entity::removeBlockFromInv(char* blockName)
{
	bool found = false;

	for(int i = Inventory.size()-1; i >= 0 && !found; i--)
	{
		if(Inventory[i]->itemName == blockName)
		{
			Inventory.remove(i);
			found = true;
		}
	}
	return found;
}
void Entity::EquipItem(int Slot, int index)
{
	//For each item, check to see if it is not empty
	//If it is, then unequip whatever item is currently in
	//Then equip the item clicked
	//If it is part of the boots or gauntlets, then also switch upper arm or thighs to the proper type. ~Tyler
	switch(Slot)
	{
	case Helmet:
		if(wornEquipment[Helmet] != NULL)										// If the current body part is taken
			UnequipItem(Helmet);												// Then unequip the current piece
		wornEquipment[Helmet] = (Item_Equippable*)Inventory[index];				// Set the piece to the selected inventory space
		wornEquipment[Helmet]->addPIE(resistPierce,resistImpact,resistEnergy);	// Add the assoicated PIE stats
		BodyParts[e_Head]->assetIndex = wornEquipment[Helmet]->assetIndex;		// Set the texture to the armors
		Inventory.remove(index);												// Remove it from inventory ~Tyler
		break;
	case Cuirass:
		if(wornEquipment[Cuirass] != NULL)
			UnequipItem(Cuirass);
		wornEquipment[Cuirass] = (Item_Equippable*)Inventory[index];
		wornEquipment[Cuirass]->addPIE(resistPierce,resistImpact,resistEnergy);
		BodyParts[e_Torso]->assetIndex = wornEquipment[Cuirass]->assetIndex;
		Inventory.remove(index);
		break;
	case Gauntlets:
		if(wornEquipment[Gauntlets] != NULL)
			UnequipItem(Gauntlets);
		wornEquipment[Gauntlets] = (Item_Equippable*)Inventory[index];
		wornEquipment[Gauntlets]->addPIE(resistPierce,resistImpact,resistEnergy);
		//For Gauntlets and boots the next four lines are used to mirror the pieces onto the opposite limbs
		// They are also used to change the textures of the upper part (Arms or Thighs) ~Tyler
		BodyParts[e_LowerArm]->assetIndex = wornEquipment[Gauntlets]->assetIndex;
		BodyParts[e_LowerArmleft]->assetIndex = wornEquipment[Gauntlets]->assetIndex;
		BodyParts[e_UpperArm]->assetIndex = wornEquipment[Gauntlets]->secassetIndex;
		BodyParts[e_UpperArmleft]->assetIndex = wornEquipment[Gauntlets]->secassetIndex;
		Inventory.remove(index);
		break;
	case Boots:
		if(wornEquipment[Boots] != NULL)
			UnequipItem(Boots);
		wornEquipment[Boots] = (Item_Equippable*)Inventory[index];
		wornEquipment[Boots]->addPIE(resistPierce,resistImpact,resistEnergy);
		BodyParts[e_Legs]->assetIndex = wornEquipment[Boots]->assetIndex;
		BodyParts[e_Legsleft]->assetIndex = wornEquipment[Boots]->assetIndex;
		BodyParts[e_Thighs]->assetIndex = wornEquipment[Boots]->secassetIndex;
		BodyParts[e_Thighsleft]->assetIndex = wornEquipment[Boots]->secassetIndex;
		Inventory.remove(index);
		break;
	case Weaponry:
		if(wornEquipment[Weaponry] != NULL)
			UnequipItem(Weaponry);
		if(Inventory[index]->itemType != ITEM_MATERIAL)
		{
			wornEquipment[Weaponry] = (Item_Equippable*)Inventory[index];
		}
		else
		{
			Item_Equippable* matToEquip = new Item_Equippable;
			matToEquip->_itemInit(ITEM_MATERIAL,0,0,Inventory[index]->itemName,&Inventory[index]->assetIndex);
			matToEquip->_equipInit(WEAP,0,0,0,0);
			wornEquipment[Weaponry] = matToEquip;
		}

		wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
		Engine::Ins()->dlHandler.AddObject(wornEquipment[Weaponry], DRAW_ENTITIES);
		Inventory.remove(index);

		break;
	}
	if(GUI_Handler::get().needsToRefreshInventory())
	{
		GUI.get().setInventory(Inventory);
		GUI.get().setEquipment((Item_Base**)(wornEquipment),MaxEquipables);

	}

	// make request to server to update this player's equipped items
	Engine::Ins()->game.m_network.MakeServerRequest(NETWORK_UPDATE_PLAYER_EQUIPS, wornEquipment, MaxEquipables);
}
void Entity::UnequipItem(int Slot)
{
	//Check to see if something is available to be unequiped
	//Take it off and add it to the inventory ~Tyler
	switch(Slot)
	{
	case Helmet:

		if(wornEquipment[Helmet] != NULL)
		{
			wornEquipment[Helmet]->remPIE(resistPierce,resistImpact,resistEnergy);	// Remove the stats associated with wearing the item
			BodyParts[e_Head]->assetIndex = SkinAssets[e_Head];						// Reset the asset to the default skin
			Inventory.push(wornEquipment[Helmet]);									// Push the piece taken off back to the inventory ~Tyler
			wornEquipment[Helmet] = NULL;
		}
		break;
	case Cuirass:
		if(wornEquipment[Cuirass] != NULL)
		{
			wornEquipment[Cuirass]->remPIE(resistPierce,resistImpact,resistEnergy);
			BodyParts[e_Torso]->assetIndex = SkinAssets[e_Torso];
			Inventory.push(wornEquipment[Cuirass]);
			wornEquipment[Cuirass] = NULL;
		}
		break;
	case Gauntlets:		
		if(wornEquipment[Gauntlets] != NULL)
		{
			wornEquipment[Gauntlets]->remPIE(resistPierce,resistImpact,resistEnergy);
			BodyParts[e_UpperArmleft]->assetIndex = SkinAssets[e_UpperArmleft];
			BodyParts[e_LowerArmleft]->assetIndex = SkinAssets[e_LowerArmleft];
			BodyParts[e_UpperArm]->assetIndex = SkinAssets[e_UpperArm];
			BodyParts[e_LowerArm]->assetIndex = SkinAssets[e_LowerArm];
			Inventory.push(wornEquipment[Gauntlets]);
			wornEquipment[Gauntlets] = NULL;
		}
		break;
	case Boots:
		if(wornEquipment[Boots] != NULL)
		{
			wornEquipment[Boots]->remPIE(resistPierce,resistImpact,resistEnergy);
			BodyParts[e_Legsleft]->assetIndex = SkinAssets[e_Legsleft];
			BodyParts[e_Thighsleft]->assetIndex = SkinAssets[e_Thighsleft];
			BodyParts[e_Legs]->assetIndex = SkinAssets[e_Legs];
			BodyParts[e_Thighs]->assetIndex = SkinAssets[e_Thighs];
			Inventory.push(wornEquipment[Boots]);
			wornEquipment[Boots] = NULL;
		}
		break;
	case Weaponry:
		if(wornEquipment[Weaponry] != NULL)
		{	
			wornEquipment[Weaponry]->SetPos(BodyParts[e_LowerArm]->getPos().x, BodyParts[e_LowerArm]->getPos().y, -1);
			Engine::Ins()->dlHandler.RemoveObjectByRef(DRAW_ENTITIES, wornEquipment[Weaponry]);
			Inventory.push(wornEquipment[Weaponry]);
			wornEquipment[Weaponry] = NULL;
		}
		break;
	}

	if(GUI_Handler::get().needsToRefreshInventory())
	{
		GUI.get().setInventory(Inventory);
		GUI.get().setEquipment((Item_Base**)(wornEquipment),MaxEquipables);
	}

	Engine::Ins()->game.m_network.MakeServerRequest(NETWORK_UPDATE_PLAYER_EQUIPS, wornEquipment, MaxEquipables);
}


/////////////////////////////////
//====Death and Damage related
/////////////////////////////////
bool Entity::TakeDamage(Item_Projectile* hitSource)
{
	//Returns true if the projectile hits a proper enemy
	if(hitSource->originFlag != entityType && alive)
	{
		if(hitSource->getPierce() > 0)
		{
			if(((short)hitSource->getPierce() - resistPierce/5) >= 0)
				currentPierce += ((short)hitSource->getPierce() - resistPierce/5);	
		}
		if(hitSource->getImpact() > 0)
		{
			if(((short)hitSource->getImpact() - resistImpact/5) >= 0)
				currentImpact += ((short)hitSource->getImpact() - resistImpact/5);
		}
		if(hitSource->getEnergy() > 0)
		{
			if(((short)hitSource->getEnergy() - resistEnergy/5) >= 0)
				currentEnergy += ((short)hitSource->getEnergy() - resistEnergy/5);
		}
		if(currentPierce >= PierceThreshold || currentImpact >= ImpactThreshold || currentEnergy >= EnergyThreshold){
			Death();
			return true;
		}
	}
	return false;
}
void Entity::Death()
{
	if(Race == 1){
#ifdef GODMODE
		currentPierce = 0; currentImpact = 0; currentEnergy = 0;	
#endif
#ifndef GODMODE
		PC_handleScore(-2);
		activeSounds[WAV_PLAYERDEATH] = true;
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x" , "Resources/Sprites/Entity/Human/Deadhead.png", NULL, NULL, ASSET_WORLD);
		alive = false;
#endif
	}
	if(Race == 2)
	{
		activeSounds[WAV_ZOMDEATH] = true;
		activeAnimations[ANI_DEATH] = true;
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x" , "Resources/Sprites/Entity/Zombie/Deadhead.png", NULL, NULL, ASSET_WORLD);
		alive = false;
	}	
	if(Race == 3 || Race == 4)
	{
		activeSounds[WAV_DRONEDEATH] = true;
		activeAnimations[ANI_DEATH] = true;
		BodyParts[e_Head]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/character mesh.x" , "Resources/Sprites/Entity/CQCDrone/DeadHead.png", NULL, NULL, ASSET_WORLD);
		BodyParts[e_Torso]->assetIndex = Engine::Ins()->graphics.AddAsset("Resources/Meshes/torso.x" , "Resources/Sprites/Entity/CQCDrone/DeadBody.png", NULL, NULL, ASSET_WORLD);
		alive = false;
	}
}
void Entity::resetPlayerfromDeath()
{
	activeAnimations[ANI_IDLE] = true;
	currentPierce = 0; currentImpact = 0; currentEnergy = 0;
	//UnequipItem(Helmet); UnequipItem(Cuirass); UnequipItem(Gauntlets); UnequipItem(Boots); UnequipItem(Weaponry); 
	if(wornEquipment[Helmet] != NULL)
		BodyParts[e_Head]->assetIndex = wornEquipment[Helmet]->assetIndex;
	else BodyParts[e_Head]->assetIndex = SkinAssets[e_Head];
	Inventory.clear();
	if(GUI_Handler::get().needsToRefreshInventory() && entityType == P_TYPE_PLAYER)
	{
		GUI.get().setInventory(Inventory);
		GUI.get().setEquipment((Item_Base**)(wornEquipment),MaxEquipables);
	}
	alive = true;
}


////////////////////////////////////////
//Placement and Rotation mutators
////////////////////////////////////////
void Entity::setPlacements(XYZ p_newPlacements[])
{
	for(int i = 0; i < e_TotalBPs; ++i)
		Placements[i] = p_newPlacements[i];
}
void Entity::setRotations(XYZ p_newRotations[])
{
	for(int i = 0; i < e_TotalBPs; ++i)
		Rotations[i] = p_newRotations[i];
}


/////////////////////////
//=====Colliding
/////////////////////////
bool Entity::CheckCollision(void * Data, bool lastXDirs[])
{
	for(int i = 0; i < DIR_SIZE; i++)
		CollidedDirections[i] = lastXDirs[i];
	RetVal* collideData = (RetVal*)Data;
	if(collideData->x && collideData->y)
	{
		//Reflection of equivalent power
		m_v3Pos.y += (Momentums[0].y * -1.0f); 
		m_v3Pos.x += (Momentums[0].x * -1.01f);	

		if(Momentums[0].x == 0)
		{
			//Reflection when there is no power
			if(!CollidedDirections[DIR_RIGHT]) m_v3Pos.x += BLOCK_TEXTURE_SIZE * 0.25f; 
			if(!CollidedDirections[DIR_LEFT]) m_v3Pos.x -= BLOCK_TEXTURE_SIZE * 0.25f; 
			//else m_v3Pos.y += BLOCK_TEXTURE_SIZE * 0.30f; 
		}

		Momentums[0].y = 0;
		Momentums[0].x = 0;

		bool secondary = false;
		for(int i = LOCAL_PLAYER+1; i < MAX_PLAYERS; ++i) {
			if(WORLD_MODULE::Ins()->Players[i])
				if(WORLD_MODULE::Ins()->Players[i] == this)
					secondary = true;
		}
		if(secondary){
			FinalMomentum.x = 0;
			FinalMomentum.y = 0;
		}

	}
	bool redo = (collideData->x && collideData->y);

	if(myJumpState != stateJumpRise)
	{
		if( CollidedDirections[DIR_DOWN])		myJumpState = stateNeutral;		
		if(!CollidedDirections[DIR_DOWN])		myJumpState = stateJumpFall;
	}
	return redo;
}
void Entity::CalcBBDimensions(float& height, float& width)
{
	height =  (Character_Mesh * 3)-2;
	width = Character_Mesh * 0.5;//By 1/2 since we scaled the body originally.
	//Both width and height are returned to be made into a bounding box
}


////////////////////////
//====Multiplayer
////////////////////////
void Entity::serialize(ByteBuffer* & info)
{
	if(!info)
		info = new ByteBuffer;
	BaseObject::serialize(info);
	info->addLong(playerIndex);
	info->addShort(Race);
	info->addLong(uniqueID);

	info->addShort(currentPierce);
	info->addShort(currentImpact);
	info->addShort(currentEnergy);

	info->addShort(PierceThreshold);
	info->addShort(ImpactThreshold);
	info->addShort(EnergyThreshold);

	info->addShort(resistPierce);
	info->addShort(resistImpact);
	info->addShort(resistEnergy);

	for(int i = 0; i < MaxEquipables; ++i)
	{
		if(!wornEquipment[i])
			info->addLong(0);
		else
		{
			info->addLong(1);
			wornEquipment[i]->serialize(info);
		}
	}

	for(int i = 0; i < ACT_MAX; ++i)
	{
		if(!CurrentActivity[i])
			info->addLong(0);
		else
		{
			info->addLong(1);
			CurrentActivity[i]->serialize(info);
		}
	}

	// serialize objects related to body parts
	for(int i = 0; i < e_TotalBPs; ++i)
	{
		Placements[i].serialize(info);

		if(!BodyParts[i])
			info->addLong(0);
		else
		{
			info->addLong(1);
			BodyParts[i]->serialize(info);
		}

		// don't need to use float values, indices should be whole numbers
		info->addLong((long)SkinAssets[i].x);
		info->addLong((long)SkinAssets[i].y);
	}
}
void Entity::deserialize(ByteBuffer* info, int & index)
{
	if(!info)
		return;
	int longSize = sizeof(long);

	// deserialize into a temp object, then assign all members from it to this
	BaseObject::deserialize(info, index);
	playerIndex = info->getLong(index); index += longSize;
	Race = info->getShort(index); index += sizeof(short);
	uniqueID = info->getLong(index); index += sizeof(long);

	currentPierce = info->getShort(index); index += sizeof(short);
	currentImpact = info->getShort(index); index += sizeof(short);
	currentEnergy = info->getShort(index); index += sizeof(short);

	PierceThreshold = info->getShort(index); index += sizeof(short);
	ImpactThreshold = info->getShort(index); index += sizeof(short);
	EnergyThreshold = info->getShort(index); index += sizeof(short);

	resistPierce = info->getShort(index); index += sizeof(short);
	resistImpact = info->getShort(index); index += sizeof(short);
	resistEnergy = info->getShort(index); index += sizeof(short);

	for(int i = 0; i < MaxEquipables; ++i)
	{
		int result = info->getLong(index);
		index += longSize;

		if(result == 0)
			wornEquipment[i] = NULL;
		else
		{
			wornEquipment[i] = new Item_Equippable;
			wornEquipment[i]->deserialize(info, index);
		}
	}

	for(int i = 0; i < ACT_MAX; ++i)
	{
		int result = info->getLong(index);
		index += longSize;

		if(result == 0)
			CurrentActivity[i] = NULL;
		else
		{
			CurrentActivity[i] = new Item_Projectile;
			CurrentActivity[i]->deserialize(info, index);
		}
	}

	// deserialize objects related to body parts
	for(int i = 0; i < e_TotalBPs; ++i)
	{
		// TODO: going to be a problem converting from long to float
		Placements[i].deserialize(info, index);

		int result = info->getLong(index);
		index += longSize;

		if(result == 0)
			BodyParts[i] = NULL;
		else
		{
			BodyParts[i] = new BaseObject;
			BodyParts[i]->deserialize(info, index);
		}

		SkinAssets[i].x = (float)info->getLong(index); index += longSize;
		SkinAssets[i].y = (float)info->getLong(index); index += longSize;
	}
}
//Inventory Mutators for Multiplayer usage
void Entity::EquipItem(int Slot, Item_Equippable* item)
{
	if(wornEquipment[Slot])
		delete wornEquipment[Slot];
	wornEquipment[Slot] = item;
	switch(Slot)
	{
	case Helmet:
		BodyParts[e_Head]->assetIndex = item->assetIndex;
		break;
	case Cuirass:
		BodyParts[e_Torso]->assetIndex = item->assetIndex;
		break;
	case Gauntlets:
		BodyParts[e_LowerArm]->assetIndex = item->assetIndex;
		BodyParts[e_LowerArmleft]->assetIndex = item->assetIndex;
		BodyParts[e_UpperArm]->assetIndex = item->secassetIndex;
		BodyParts[e_UpperArmleft]->assetIndex = item->secassetIndex;
		break;
	case Boots:
		BodyParts[e_Legs]->assetIndex = item->assetIndex;
		BodyParts[e_Legsleft]->assetIndex = item->assetIndex;
		BodyParts[e_Thighs]->assetIndex = item->secassetIndex;
		BodyParts[e_Thighsleft]->assetIndex = item->secassetIndex;
		break;
	case Weaponry:
		float x = BodyParts[e_LowerArm]->getPos().x;
		float y = BodyParts[e_LowerArm]->getPos().y;
		item->SetPos(x, y, -1);
		Engine::Ins()->dlHandler.AddObject(item, DRAW_ENTITIES);
	}

}
void Entity::UnequipItemM(int Slot)
{
	if(!wornEquipment[Slot])
		return;

	if(Slot != Weaponry)
		delete wornEquipment[Slot];
	switch(Slot)
	{
	case Helmet:
		BodyParts[e_Head]->assetIndex = SkinAssets[e_Head];
		break;
	case Cuirass:
		BodyParts[e_Torso]->assetIndex = SkinAssets[e_Torso];
		break;
	case Gauntlets:
		BodyParts[e_UpperArmleft]->assetIndex = SkinAssets[e_UpperArmleft];
		BodyParts[e_LowerArmleft]->assetIndex = SkinAssets[e_LowerArmleft];
		BodyParts[e_UpperArm]->assetIndex = SkinAssets[e_UpperArm];
		BodyParts[e_LowerArm]->assetIndex = SkinAssets[e_LowerArm];
		break;
	case Boots:
		BodyParts[e_Legsleft]->assetIndex = SkinAssets[e_Legsleft];
		BodyParts[e_Thighsleft]->assetIndex = SkinAssets[e_Thighsleft];
		BodyParts[e_Legs]->assetIndex = SkinAssets[e_Legs];
		BodyParts[e_Thighs]->assetIndex = SkinAssets[e_Thighs];
		break;
	case Weaponry:
		Item_Equippable* item = wornEquipment[Weaponry];
		if(item)
		{
			Engine::Ins()->dlHandler.RemoveObjectByRef(DRAW_ENTITIES, item);
			delete item;
		}
		break;
	}
	wornEquipment[Slot] = NULL;
}
//Updates for multiplayer usage
void Entity::UpdateSecondaryEntity()
{
	if(bGravity)
		FinalMomentum.y += Gravity;

	if(!CollidedDirections[DIR_UP] && FinalMomentum.y > 0)
		m_v3Pos.y += FinalMomentum.y;
	if(!CollidedDirections[DIR_DOWN] && FinalMomentum.y < 0)
		m_v3Pos.y += FinalMomentum.y;
	if(!CollidedDirections[DIR_LEFT] && FinalMomentum.x > 0)
		m_v3Pos.x += FinalMomentum.x;
	if(!CollidedDirections[DIR_RIGHT] && FinalMomentum.x < 0)
		m_v3Pos.x += FinalMomentum.x;


	if(FinalMomentum.y < 0)
		myJumpState = stateJumpFall;


	UpdateLimbs();
	UpdateWornItems();

	if(FinalMomentum.x > 0)
		Flip(DIR_RIGHT);
	else
		Flip(DIR_LEFT);
}
void Entity::CalcMomentumM(Vector3D pos, Vector2D p)
{
	FinalMomentum = p;

	if(fabs(m_v3Pos.x - pos.x) >= 35.0f || 
		fabs(m_v3Pos.y - pos.y) >= 35.0f)
		m_v3Pos = pos;
	// TODO: Factor in the sent position and modify the momentum based on that
}
void Entity::setDamages(short p, short i, short e) 
{
	currentPierce = p; currentImpact = i; currentEnergy = e;
	if(currentPierce >= PierceThreshold || 
		currentImpact >= ImpactThreshold ||
		currentEnergy >= EnergyThreshold)
		Death();
}
